package org.eclipse.emf.cdo.ui.merge;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.spi.cdo.DefaultCDOMerger.ChangedInSourceAndDetachedInTargetConflict;
import org.eclipse.emf.spi.cdo.DefaultCDOMerger.ChangedInSourceAndTargetConflict;
import org.eclipse.emf.spi.cdo.DefaultCDOMerger.ChangedInTargetAndDetachedInSourceConflict;
import org.eclipse.emf.spi.cdo.DefaultCDOMerger.Conflict;

/**
 * Generates the tree with a main node "Conflicts".
 * @author Thomas Halmetschlager
 *
 */
public class CDOConflictProcessor {
	
	/** The conflicts. */
	private Map<CDOID, Conflict> conflicts;
	
	/**
	 * Instantiates a new CDO conflict processor.
	 *
	 * @param conflicts the map of conflicts
	 */
	public CDOConflictProcessor(Map<CDOID, Conflict> conflicts) {
		this.conflicts=conflicts;
	}
	
	/**
	 * Generates the tree containing the conflicts if there are any.
	 *
	 * @param sourceBranch the source branch
	 * @param targetBranch the target branch
	 * @return the list of conflicts
	 */
	public List<TreeObject> generateTree(CDOBranch sourceBranch, CDOBranch targetBranch){
		ArrayList<TreeObject> conflictTree = new ArrayList<TreeObject>();

		if(conflicts != null){
			TreeParent rootConflict = new TreeParent("Conflicts");
			
			for(CDOID conflcitID : conflicts.keySet()){
				Conflict conflict = conflicts.get(conflcitID);
				ConflictTreeParent treeParent = new ConflictTreeParent("conflict", conflict);
				
				if(conflict instanceof ChangedInSourceAndTargetConflict){
					ChangedInSourceAndTargetConflict typicalConflict = (ChangedInSourceAndTargetConflict) conflict;
					ConflictTreeObject targetNode = new ConflictTreeObject("Target", typicalConflict.getTargetDelta());
					ConflictTreeObject srcNode = new ConflictTreeObject("Source", typicalConflict.getSourceDelta());
					
					treeParent.addChild(targetNode);
					treeParent.addChild(srcNode);
					
				}
				if(conflict instanceof ChangedInSourceAndDetachedInTargetConflict){
					ChangedInSourceAndDetachedInTargetConflict typicalConflict = (ChangedInSourceAndDetachedInTargetConflict) conflict;
					TreeObject targetNode = new TreeObject("Target: delete");
					ConflictTreeObject srcNode = new ConflictTreeObject("Source", typicalConflict.getSourceDelta());
					
					treeParent.addChild(targetNode);
					treeParent.addChild(srcNode);
				}
				if(conflict instanceof ChangedInTargetAndDetachedInSourceConflict){
					ChangedInTargetAndDetachedInSourceConflict typicalConflict = (ChangedInTargetAndDetachedInSourceConflict) conflict;
					ConflictTreeObject targetNode = new ConflictTreeObject("Target", typicalConflict.getTargetDelta());
					TreeObject srcNode = new TreeObject("Source: Delete");
					
					treeParent.addChild(targetNode);
					treeParent.addChild(srcNode);
				}
				
				rootConflict.addChild(treeParent);
			}
			conflictTree.add(rootConflict);
		}
		return conflictTree;
	}

}
